この本を見ながら進めてる↓
前回⇒「【Swift奮闘記ep15】イニシャライザとデイニシャライザについて」
イニシャライザを終えて今回は継承について学ぶ。
継承とは文字どおり、何かを「受け継ぐ」ことだ。
Aがもっている機能をBに受け継がせる方法をみていく。
今回はクラスの継承、あとイニシャライズの継承、さらに上書きするオーバーライド、親クラスのプロパティやメソッドを子クラスが使えるようにするsuperキーワードについて学ぶ。
クラスの継承
さっそく、ザクザクコードを打ってみた。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
class Wagon { //Wagonクラスを作成 var persons = 0 //変数personsを定義 func ride() { //メソッドride()を定義 persons += 1 //personsに1足す } } class Car: Wagon { //Wagonクラスを継承したCarクラスを定義 let tires = 4 //定数tiresを定義 } var a = Car() //Carクラスをインスタンス化 a.ride() //rideメソッドを実行 a.persons //rideメソッドを実行するたびにpersonsの値が増えていく。 //CarクラスのインスタンスからWagonクラスのメソッドとプロパティを呼び出せていることを確認する。 a.tires //Carクラスのプロパティも一応確認。 |
ということでクラスを継承することによって元のクラスの機能を使うことができる。
元のクラスのことを「スーパークラス(又はベースクラス)」、承継先のクラスを「サブクラス」というので覚えておこう。
オーバーライド
クラスの継承を行いつつ、インスタンスプロパティ・型プロパティ・インスタンスメソッド・型メソッド・サブスクリプトの単位で上書きをする機能をオーバーライドという。
宣言の頭にoverrideとつければ以下のようにオーバーライドできる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
class Wagon { //Wagonクラスを作成 var persons = 0 //変数personsを定義 func ride() { //メソッドride()を定義 persons += 1 //personsに1足す } } class Car: Wagon { //Wagonクラスを継承したCarクラスを定義 let limit = 4 //定数limitを定義 override func ride() { //override を頭につけて上書きさせる。 if(persons < limit) { //if文で定数limitの値未満のときにだけpersonsを1増やす。 persons += 1 } } } var a = Car() //カークラスのインスタンス化 for _ in 1...10 { //ためしに繰り返し処理を行ってみる。 a.ride() //10回ride()処理を行っても10にはならず。 } a.persons //4であることが確認できる。 |
比較的簡単にオーバーライドできることがわかる。
superキーワード
さらに親クラス(スーパークラス)で定義したプロパティやメソッドを子クラス(サブクラス)で使うことができる。
オーバーライドのところで説明したコードを変更させる。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
class Car: Wagon { //Wagonクラスを継承したCarクラスを定義 let limit = 4 //定数limitを定義 override func ride() { //override を頭につけて上書きさせる。 if(persons < limit) { //if文で定数limitの値未満のときにだけpersonsを1増やす。 super.ride() } } |
super.ride()というふうに書き換えて「numberOfPersons += 1」 を表現した。
イニシャライザの継承
クラスを承継する際に、イニシャライザも承継することができる。
ただ条件?みたいなものがあって、悩ましい。
スーパークラスにイニシャライザが定義されているとして、その際サブクラスにイニシャライザを定義していなければ、スーパークラスのイニシャライザがそのまま継承される。
もしサブクラスにイニシャライザを定義する場合は、スーパークラスのイニシャライザをサブクラス内のイニシャライザ内で再定義しないといけないようだ。
再定義っていう言葉が正しいかどうかはわからんが、その方法が複雑というかいまいちあまり意味がわかっていない。
※追記
「再定義」というのは間違いでスーパークラスのイニシャライザを「呼び出す」が正解。
「すでに定義してあるイニシャライズを使う必要がある」ということだ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class Vezel { var a: Int init (a: Int) { self.a = a } } class Car: Vezel { var b: Int init(a: Int, b: Int) { self.b = b super.init(a: a) } } var c = Car(a: 4, b: 5) c.a c.b |
super.init(a: a)のところがさっぱり意味不明だ。
この部分がスーパークラスのイニシャライザを定義しているというのはわかるのだが、(a: a)がわからない。aは引数、:の横のaは・・・ここはIntなどの型を入れる場所じゃないのかな?
わからんな〜。そのうちわかるのだろうか。
まあこれは疑問として覚えておこう。
※追記
「サブクラスでイニシャライザが設定されている」のでサブクラス内でスーパークラスのイニシャライザを「呼び出す」必要がある。
super.init(a:a)の引数である「a」にはサブクラスで与えられる引数のaの値を代入する、という意味になる。
今回はこれにて終わり。
続き⇒「【Swift奮闘記ep17】ストラクチャ(ストラクチャの定義、できること、参照型と値型の違い、プロパティ・イニシャライザ)」
コメント